/**
 *  Copyright (C) 2011  Thomas ROBIN
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package triseries;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

/**
 * @author tshepo
 * 
 */
public class Download extends Thread {

	private static final boolean DEBUG = (Main.debug || MyProperties.debug.equalsIgnoreCase("Download"));
	private String dest;
	private String name;
	private String bestSubtitle;
	private String filename;
	private String url;
	private Download old;
	private final String fileExport;
	private String status;

	Download(BTSubtitles bts, String dest, String name, String fileExport,
			Download old) {
		if(DEBUG) System.err.println("Download()");
		this.dest = dest;
		this.name = name;
		this.old = old;
		this.bestSubtitle = bts.bestSubtitle();
		this.filename = bts.getFile();
		this.url = bts.getUrl();
		this.fileExport = fileExport;
	}

	@Override
	public void run() {
		if(DEBUG) System.err.println("Download.run()");
		String status = "Waiting for download of " + filename;
		File destination = null;
		// attente du téléchargement précédent
		if (old != null) {
			try {
				old.join();
			} catch (InterruptedException e) {
				ProcessErr(e.getStackTrace().toString(), destination);
				return;
			}
		}

		status = "Starting download of " + filename;
		if(DEBUG) System.err.println("Download.run() "+status);

		if (Main.debug || MyProperties.verbose) {
			System.out.println(status);
		}
		// Si le dossier de destination n'existe pas, on le creer
		if (!(new File(dest)).exists()) {
			(new File(dest)).mkdirs();
		}
		URL u = null;
		try {
			// on passe direct en https
			u = new URL(url.replace("http", "https"));
		} catch (MalformedURLException e) {
			ProcessErr(e.getStackTrace().toString(), destination);
			return;
		}
		destination = new File(dest + File.separator + filename);
		// si le fichier existe, pas besoin de le re-télécharger
		if (destination.exists()) {
			Main.processWarning("Le programe a demander de télécharger "+ filename +" alors qu'il existe déjà");
			return;
		}
		URLConnection uc = null;
		try {
			uc = u.openConnection();
		} catch (IOException e) {
			ProcessErr(e.getStackTrace().toString(), destination);
			return;
		}
		InputStream in = null;
		try {
			in = uc.getInputStream();
		} catch (IOException e) {
			ProcessErr(e.getStackTrace().toString(), destination);
			return;
		}
		FileOutputStream WritenFile = null;
		try {
			WritenFile = new FileOutputStream(destination);
		} catch (FileNotFoundException e) {
			ProcessErr(e.getStackTrace().toString(), destination);
			return;
		}
		if (!destination.getParentFile().exists())
			destination.getParentFile().mkdirs();
		status = "downloading " + filename;
		if(DEBUG) System.err.println("Download.run() "+status);
		byte[] buff = new byte[1024];
		int l = 0;
		try {
			l = in.read(buff);
		} catch (IOException e) {
			ProcessErr(e.getStackTrace().toString(), destination);
			return;
		}
		while (l > 0) {
			try {
				WritenFile.write(buff, 0, l);
			} catch (IOException e) {
				ProcessErr(e.getStackTrace().toString(), destination);
				return;
			}
			try {
				l = in.read(buff);
			} catch (IOException e) {
				ProcessErr(e.getStackTrace().toString(), destination);
				return;
			}
		}
		try {
			WritenFile.flush();
		} catch (IOException e) {
			ProcessErr(e.getStackTrace().toString(), destination);
			return;
		}
		try {
			WritenFile.close();
		} catch (IOException e) {
			ProcessErr(e.getStackTrace().toString(), destination);
			return;
		}
		status = "Download complete of" + filename;
		if(DEBUG) System.err.println("Download.run() "+status);

		if (Main.debug || MyProperties.verbose) {
			System.out.println("Téléchargement terminé");
		}

		/**
		 * Si le fichier est bien un ZIP, extrait le soustitre de l'archive et
		 * la supprime
		 */
		if (destination.getName().endsWith(".zip")
				|| destination.getName().endsWith(".ZIP")) {

			status = "opening " + destination.getName();
			if(DEBUG) System.err.println("Download.run() "+status);
			UnZip uz = new UnZip(destination);
			String to = dest + File.separator + name;
			status = "Unzipping " + bestSubtitle + " from "
					+ destination.getName() + " to " + to;
			if(DEBUG) System.err.println("Download.run() "+status);
			if (uz.Extract(bestSubtitle, to) < 0)
				FileAcces.saveForLater(fileExport + "\n");
			if (Main.debug || MyProperties.verbose) {
				System.out.println("Extraction terminé");
			}
		}

		destination.delete();

	}

	private void ProcessErr(String e, File destination) {
		Main.processExeption("Download.run\nWhile " + status+" :\n"
				+ e);
		FileAcces.saveForLater(fileExport + "\n");
		if (Main.debug || MyProperties.verbose) {
			System.out.println("Suppression de " + destination.getName());
		}
		if (!Main.debug) {
			destination.delete();
		} else {
			destination.renameTo(new File(destination.getAbsolutePath()
					.replace("\\.zip", "_BAD.zip")));
		}
	}
}
